package com.test.list.adapter;

/** Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/
import java.util.List;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.SectionIndexer;

import com.test.list.interfaces.Viewable;
import com.test.list.views.AmazingListView;

public abstract class AmazingAdapter extends ArrayAdapter<Viewable> implements
		SectionIndexer, OnScrollListener
{

	public AmazingAdapter(Context context, int textViewResourceId,
			List<Viewable> objects)
	{
		super(context, textViewResourceId, objects);
	}

	public static final String TAG = AmazingAdapter.class.getSimpleName();

	/**
	 * Pinned header state: don't show the header.
	 */
	public static final int PINNED_HEADER_GONE = 0;

	/**
	 * Pinned header state: show the header at the top of the list.
	 */
	public static final int PINNED_HEADER_VISIBLE = 1;

	/**
	 * Pinned header state: show the header. If the header extends beyond the
	 * bottom of the first shown element, push it up and clip.
	 */
	public static final int PINNED_HEADER_PUSHED_UP = 2;

	/**
	 * Computes the desired state of the pinned header for the given position of
	 * the first visible list item. Allowed return values are
	 * {@link #PINNED_HEADER_GONE}, {@link #PINNED_HEADER_VISIBLE} or
	 * {@link #PINNED_HEADER_PUSHED_UP}.
	 */
	public int getPinnedHeaderState(int position)
	{
		if (position < 0 || getCount() == 0)
		{
			return PINNED_HEADER_GONE;
		}

		// The header should get pushed up if the top item shown
		// is the last item in a section for a particular letter.
		int section = getSectionForPosition(position);
		int nextSectionPosition = getPositionForSection(section + 1);
		if (nextSectionPosition != -1 && position == nextSectionPosition - 1)
		{
			return PINNED_HEADER_PUSHED_UP;
		}

		return PINNED_HEADER_VISIBLE;
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount)
	{
		if (view instanceof AmazingListView)
		{
			((AmazingListView) view).configureHeaderView(firstVisibleItem);
		}
	}

	@Override
	public final View getView(int position, View convertView, ViewGroup parent)
	{
		View res = getAmazingView(position, convertView, parent);

		final int section = getSectionForPosition(position);
		boolean displaySectionHeaders = (getPositionForSection(section) == position);

		bindSectionHeader(res, position, displaySectionHeaders);

		return res;
	}

	/**
	 * The last item on the list is requested to be seen, so do the request and
	 * call {@link AmazingListView#tellNoMoreData()} if there is no more pages.
	 * 
	 * @param page
	 *            the page number to load.
	 */
	// protected abstract void onNextPageRequested(int page);

	/**
	 * Configure the view (a listview item) to display headers or not based on
	 * displaySectionHeader (e.g. if displaySectionHeader
	 * header.setVisibility(VISIBLE) else header.setVisibility(GONE)).
	 */
	protected abstract void bindSectionHeader(View view, int position,
			boolean displaySectionHeader);

	/**
	 * read: get view too
	 */
	public abstract View getAmazingView(int position, View convertView,
			ViewGroup parent);

	/**
	 * Configures the pinned header view to match the first visible list item.
	 * 
	 * @param header
	 *            pinned header view.
	 * @param position
	 *            position of the first visible list item.
	 * @param alpha
	 *            fading of the header view, between 0 and 255.
	 */
	public abstract void configurePinnedHeader(View header, int position,
			int alpha);

	@Override
	public abstract int getPositionForSection(int section);

	@Override
	public abstract int getSectionForPosition(int position);

	@Override
	public abstract Object[] getSections();

	public abstract void hideKeyboard();
}
